﻿using Ewell.BizComponent.Service.IServer;
using Ewell.BizComponent.Service.Model.Dto;
using Ewell.BizComponent.Service.Model.Dto.OutSettlement;
using Ewell.BizComponent.Service.Model.Request;
using Ewell.BizComponent.Service.Model.Response;
using Ewell.Interface.Common.Model.Common;
using Ewell.Interface.Common.Model.GateWay.Dto.Out;
using Ewell.Interface.Common.Model.GateWay.GateWayUriInfo;
using Ewell.Interface.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Ewell.BizComponent.Service.Server
{
    /// <summary>
    /// 收费服务
    /// </summary>
    public class OutSettlementServer : IOutSettlementServer
    {
        private OutSettlementManageDubboService outSettlementManageDubboService = new OutSettlementManageDubboService();
        /// <summary>
        /// 收费预算
        /// </summary>
        PreSettlementResponse IOutSettlementServer.PreSettlement(OutPreSettlementRequest request)
        {
            PreSettlementResponse result = new PreSettlementResponse();
            List<BillItemDTO> billItemDTOs = new List<BillItemDTO>();
            foreach (var item in request.preSettlementList)
            {
                foreach (var bill in item.billItemList)
                {
                    BillItemDTO billItem = new BillItemDTO();
                    billItem.billItemId = bill.billItemId;
                    billItem.isDrug = bill.isDrug;
                    billItem.herbNumber = bill.herbNumber ?? 1;
                    billItem.presByDocId = bill.presByDocId;
                    billItem.presByDeptId = bill.presByDeptId;
                    billItem.execDeptId = bill.execDeptId;
                    billItem.presId = bill.presId;
                    billItem.presedAt = bill.presedAt;
                    List<CommodityDTO> commodityDTOs = new List<CommodityDTO>();
                    foreach (var commodity in bill.commodityList)
                    {
                        CommodityDTO commodityDTO = new CommodityDTO();
                        commodityDTO.commodityId = commodity.commodityId;
                        commodityDTO.commodityTypeCoding = commodity.commodityTypeCoding;
                        commodityDTO.retailPrice = commodity.retailPrice;
                        commodityDTO.commodityQuantity = commodity.commodityQuantity;
                        commodityDTO.commodityUnitName = commodity.commodityUnitName;
                        commodityDTO.clinicOrderDetailId = commodity.clinicOrderDetailId;
                        commodityDTO.presDetailId = commodity.presDetailId;
                        commodityDTO.retailUnitFactor = commodity.retailUnitFactor;
                        commodityDTO.insurMinUploadFlag = commodity.insurMinUploadFlag;
                        commodityDTO.tcmDrugUsedWay = commodity.tcmDrugUsedWay;
                        commodityDTO.needUploadFlag = commodity.needUploadFlag ?? "1";
                        commodityDTO.medicareCheckStatus = commodity.medicareCheckStatus ?? "1";
                        commodityDTOs.Add(commodityDTO);
                    }
                    billItem.commodityList = commodityDTOs;
                    List<OrderDetailDTO> orderDetailDTOs = new List<OrderDetailDTO>();
                    if (bill.orderDetailList != null)
                        foreach (var orderDetail in bill.orderDetailList)
                        {
                            OrderDetailDTO orderDetailDTO = new OrderDetailDTO()
                            {
                                orderDetailId = orderDetail.orderDetailId,
                                orderDetailTypeCoding = orderDetail.orderDetailTypeCoding,
                                orderItemId = orderDetail.orderItemId,
                                orderItemName = orderDetail.orderItemName,
                                presDetailIds = orderDetail.presDetailIds,
                                presDetails = orderDetail.presDetailIds,
                                quantityCharged = orderDetail.quantityCharged,
                            };
                            orderDetailDTOs.Add(orderDetailDTO);
                        }
                    billItem.orderDetailList = orderDetailDTOs;
                    billItemDTOs.Add(billItem);
                }
            }
            //门诊收费预算
            OutSettlementPreRequest settlementPreRequest = new OutSettlementPreRequest()
            {
                bizSourceCoding = request.bizSourceCoding,
                patientId = request.patient.patientId,
                outEncounterId = request.encounter.encounterId.ToString(),
                patientName = request.patient.patientName,
                payType = request.settlementTypeCode,//1-挂号 2-收费
                billId = GuidHelper.GenerateUnique19DigitId(),
                insurTypeId = request.preSettlementList.FirstOrDefault()?.insurTypeId,
                billItemList = billItemDTOs,

            };
            var gateWayPreSettlement = outSettlementManageDubboService.outSettlementPre.Post<OutSettlementPreResponse>(settlementPreRequest).CheckState("诊间挂号");
            result.settlementId = gateWayPreSettlement.@object.settlementId;
            result.settlementTypeCode = settlementPreRequest.payType;
            result.amount = gateWayPreSettlement.@object.amount;
            result.discountAmount = gateWayPreSettlement.@object.discountAmount;
            return result;
        }

        /// <summary>
        /// 收费正算
        /// </summary>
        OutSettlementResponse IOutSettlementServer.Settlement(Model.Request.OutSettlementRequest request)
        {
            OutSettlementResponse result = new OutSettlementResponse();
            //门诊收费正算
            List<PayRecordDTO> payRecordList = new List<PayRecordDTO>();
            foreach (var item in request.settlementInfo.payRecordList)
            {
                PayRecordDTO payRecord = new PayRecordDTO
                {
                    payAmount = item.payAmount,
                    payWayId = item.payWayId,
                    thirdPartTranId = item.thirdPartTranId,
                    insurPaymentFlag = string.IsNullOrWhiteSpace(item.insurPaymentFlag) ? "0" : item.insurPaymentFlag,
                };
                payRecordList.Add(payRecord);
            }
            Interface.Common.Model.GateWay.Dto.Out.OutSettlementRequest settlementRequest = new Interface.Common.Model.GateWay.Dto.Out.OutSettlementRequest()
            {
                settlementId = request.settlementInfo.settlementId,
                payTypeCoding = request.settlementInfo.payTypeCoding,
                outEncounterId = request.settlementInfo.outEncounterId,
                amount = request.settlementInfo.amount,
                discountAmount = request.settlementInfo.discountAmount,
                insurAmount = request.settlementInfo.insurAmount,
                selfPayAmount = request.settlementInfo.selfPayAmount,
                payRecordList = payRecordList,
            };
            var gateWaySettlement = outSettlementManageDubboService.outSettlement.Post<object>(settlementRequest);
            if (!gateWaySettlement.success) throw new SpeedException("门诊收费", gateWaySettlement.message);

            return result;
        }
    }
}
